//
// Created by iimt on 21-2-25.
//

#include "currencyChassis_registerServiceWindow.h"


/**
 * sukai
 * 数据库 sqllite
 *
 * 22-01-18
 * 系统注册，授权服务
 * rosrun slamservice currencyChassis_registerServiceMain_node
 *
 */


RegisterService::RegisterService( QWidget *parent): QWidget(parent) {

    //初始化控件和布局
    initWidgets();
    //信号
    bindSignal();

    recv_prefix_green = "<font color='green'> &nbsp; &nbsp; &nbsp; &nbsp; "; // 空格：“&nbsp;”
    recv_prefix_red = "<font color='red'> &nbsp; &nbsp; &nbsp; &nbsp; "; // 空格：“&nbsp;”


}

RegisterService::~RegisterService() = default;

//sukai 发送数据
void RegisterService::sendMsg(QString msg)
{
  IIMTDriver::getInstance()->sendMsg(msg);

}

//sukai 设置返回函数
void RegisterService::setCallBack()
{

     // todo sukai 2022-01-22  接收授权码服务验证结果
    IIMTDriver::getInstance()->setRegisterServiceResult_CallBack([this](QString registerServiceResult){
        try {
/**
            参数说明：
                                     名称	         说明	                         	                 备注
                                    success              授权码验证结果 成功
                                    aborted              授权码验证结果 失败
                                    emailSuccess         发送授权码到邮箱   成功
                                    emailAborted         发送授权码到邮箱   失败
                                    emailSuccessFromHttp 发送授权码到邮箱http通讯   失败
                                    emailAbortedFromHttp 发送授权码到邮箱http通讯    失败
                                    registerSuccess      邮箱中的授权码注册系统 成功
                                    registerAborted      邮箱中的授权码注册系统 失败
                                    againSuccess         授权码验证结果成功，不需要再次验证操作；
*/
            qDebug()<<" =======================  接收授权码服务验证结果========================== ";
            qDebug()<<"接收授权码服务验证结果 registerServiceResult "<<registerServiceResult;
          //   ui->robot_status->setText(robotStatus);

             if(registerServiceResult=="success" ||registerServiceResult=="againSuccess"){
                 show_console("slam授权成功！"+registerServiceResult,"send");
              QMessageBox::about(this, tr("提示："), "slam授权成功！");
             }else if(registerServiceResult=="aborted"){
               QMessageBox::about(this, tr("提示："), "slam授权失败！");
                show_console("slam授权失败！"+registerServiceResult,"send");
             }else if(registerServiceResult=="emailSuccess"){
                 show_console("获取机器硬件序号成功！"+registerServiceResult,"send");
            }else if(registerServiceResult=="emailAborted"){
                 show_console("获取机器硬件序号失败！"+registerServiceResult,"send");
                 QMessageBox::about(this, tr("提示："), "获取机器硬件序号失败！"+registerServiceResult);

            }else if(registerServiceResult=="registerSuccess"){
                 show_console("授权码正确！"+registerServiceResult,"send");
            }else if(registerServiceResult=="registerAborted"){
                 show_console("授权码不正确！"+registerServiceResult,"send");
                 QMessageBox::about(this, tr("提示："), "授权码不正确！！"+registerServiceResult);

            }else if(registerServiceResult=="emailSuccessFromHttp"){
                  show_console("获取授权码成功，请前往邮箱中查看！"+registerServiceResult,"send");
               QMessageBox::about(this, tr("提示："), "获取授权码成功，请前往邮箱中查看！");
             }else if(registerServiceResult=="emailAbortedFromHttp"){
                  show_console("获取授权码失败！"+registerServiceResult,"send");
                 QMessageBox::about(this, tr("提示："), "获取授权码失败！"+registerServiceResult);

             }else{
                 QMessageBox::about(this, tr("提示："), registerServiceResult);
                 show_console(registerServiceResult,"send");
             }

        } catch (std::exception e) {
            cout << " setRegisterServiceResult_CallBack 行异常！" << endl;
        }
    });
}


void RegisterService::initWidgets() {

    editFirst =new QLineEdit(this);
    editSecond =new QLineEdit(this);
      editThird =new QLineEdit(this);
      editFifth =new QLineEdit(this);

    //窗体设置
    setWindowTitle("slam授权系统_TCP_GUI");
    //设置窗体大小
    //resize(500, 520);
    setFixedSize(1030, 499);
    QHBoxLayout  *Hlayout = new QHBoxLayout;
    QHBoxLayout  *Hlayout2 = new QHBoxLayout;
    QVBoxLayout  *Vlayout = new QVBoxLayout;
    //设置布局
    layout = new QFormLayout();
    Vlayout->addLayout(layout);
    setLayout(Vlayout);


    //下拉框选桌号
    editFirst->move(100, 20);
    // editFirst->addItems(texts);
    layout->addRow("请输入邮箱中的授权码：", editFirst);

    editSecond->move(100, 20);
       layout->addRow("底盘编号：", editSecond);
       editThird->move(100, 20);
       layout->addRow("商户编号：", editThird);
       editFifth->move(100, 20);
       layout->addRow("商户名称：", editFifth);

    //送餐
    btnSend = new QPushButton("获取授权码");
    //输入授权码
    btnBackSend = new QPushButton("注册授权码");
    //授权slam系统
    cancelBtn = new QPushButton("授权slam系统");
    reBtnSend = new QPushButton("重置");
    //layout->addWidget(btnSend);
    Hlayout2->addWidget(btnSend);
    Hlayout2->addWidget(btnBackSend);
    Hlayout->addWidget(cancelBtn);
    Hlayout->addWidget(reBtnSend);
    layout->addRow("", Hlayout2);
    layout->addRow("", Hlayout);

    //清除日志
    clear_logBtn.setText("清除日志");

    layout->addWidget(&clear_logBtn);
    layout->addWidget(&logTextEdit);

}



void RegisterService::bindSignal() {

    //获取邮箱授权码
    btnSend->connect(btnSend, &QPushButton::clicked, this, &RegisterService::clickSend);
    //注册授权码
    btnBackSend->connect(btnBackSend, &QPushButton::clicked, this, &RegisterService::clickSendBack);

    //授权slam系统,获得授权结果
    cancelBtn->connect(cancelBtn, &QPushButton::clicked, this, &RegisterService::cancelGoal);
    //重置
    btnSend->connect(reBtnSend, &QPushButton::clicked, this, &RegisterService::reClickSend);
    //清除日志
    connect(&clear_logBtn, &QPushButton::clicked, this, &RegisterService::clear_log);
}

//检查数据库文件(所有类型)是否存在
// 1:存在 0:不存在
int RegisterService::IsFileExist(const char* path)
{
    return !access(path, F_OK);
}




//=======================gui======================
//1. todo 获取授权码 | 发送加密的授权码到邮箱中 gui
void RegisterService::clickSend() {
    QString msg="/api/registerService?state=sendemail";
    //1.底盘编号
      QString editSecondText = editSecond->text();
      //去除所有空白
      editSecondText = editSecondText.remove(QRegExp("\\s"));
      if(editSecondText.size()>0){
          //机器人编号封装
          msg=msg+"&robotNumber="+QString::fromStdString(robotNumber);
      }else{
          QMessageBox::about(this, tr("提示："), "请输入底盘编号！");
          return;
      }

      //2.商户编号
      QString editThirdText = editThird->text();
      //去除所有空白
      editThirdText = editThirdText.remove(QRegExp("\\s"));
      if(editThirdText.size()>0){
          //商户编号封装
          msg=msg+"&merchantNumber="+QString::fromStdString(merchantNumber);

      }else{
          QMessageBox::about(this, tr("提示："), "请输入商户编号！");
           return;
      }

      //3.商户名称
      QString editFifthText = editFifth->text();
      //去除所有空白
      editFifthText = editFifthText.remove(QRegExp("\\s"));
      if(editFifthText.size()>0){
          //商户名称封装
          msg=msg+"&merchantName="+QString::fromStdString(merchantName);

      }else{
          QMessageBox::about(this, tr("提示："), "请输入商户名称！");
           return;
      }





    sendMsg(msg);
    show_console(" 正在获取授权码","send");


}

//2. todo 输入邮箱中的授权码注册,注册slam系统  gui
void RegisterService::clickSendBack() {


            //2.把用户输入的 checkenconde 加密码保存到文件中
            QString editFirstText = editFirst->text();
            //去除所有空白
            editFirstText = editFirstText.remove(QRegExp("\\s"));
            if(editFirstText.size()>0){

                //正则匹配数值包括负数 小数 整数
                std::string str{ "^[1-9]\\d*$" };
                std::regex re(str);

                string  editFirstTextString=   editFirstText.toStdString();
                bool retMatchStr= false;
                retMatchStr = std::regex_match(editFirstTextString, re);
                if (!retMatchStr)
                {
                    show_console(" 请输入正确的整数","send");
                    QMessageBox::about(this, tr("警告："), "请输入正确的整数授权码！");
                    return;
                }else{
                    QString msg="/api/registerService?state=register&checkcode="+editFirstText;
                    sendMsg(msg);
                    show_console(" 正在授权码中","send");
                }



            }else{

                show_console(" 请输入正确的整数","send");
                QMessageBox::about(this, tr("警告："), "请输入授权码！");

            }


}

//3. todo 授权slam系统,获得授权结果 gui
void RegisterService::cancelGoal(){

    QString msg="/api/registerService?state=registerResult";
    sendMsg(msg);
    show_console(" 正在获取授权结果！","send");


}

//=======================time======================


//重置
void RegisterService::reClickSend(){
    initvariable();
}


//==========================================

//注册文件写入
void RegisterService::wrirtFile(QString &msg){
    vector<QString> msgs;
    //读取文件

    QString filepath1=QString::fromStdString(log_file_path)+"registerService.txt";
    QFile file(filepath1);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug()<<"Can't open the file!"<<endl;
    }

    while(!file.atEnd()) {
        QByteArray line = file.readLine();
        QString msg(line);
        msgs.push_back(msg);
    }
    //重新写入文件
    QFile filewirt(filepath1);
    filewirt.open(QIODevice::WriteOnly);
    QTextStream ts(&filewirt);
    ts.setCodec(QTextCodec::codecForName("UTF-8"));
    for (int i = 0; i < msgs.size(); ++i) {
//   QString  msg0 = msg.remove(QRegExp("\\s"));
       // qDebug()<<"msg: "<<msgs[i]<<endl;
       // qDebug()<<"===msg====: "<<msgs[i].size()<<endl;
        if(msgs[i].size()>2){
            QStringList msgl =  msgs[i].split("-");
           if(msgl[0]=="checkenconde"){
                QString OutTxt =msg;
                ts << OutTxt << endl;
            }else{
                ts << msgs[i] << endl;
            }
        }

    }

}

/**
 * 保存注册文件
 * 1:QIODevice::WriteOnly 2:QIODevice::WriteOnly | QIODevice::Append
 */
void RegisterService::saveRegisterFile(vector<QString> msgs,int i)
{

//自动创建目录
//--------------------还没测试-----------------------------

    try {
        char file_path[1500] = {0};
//        std::string home = getenv("HOME");
//        std::string log_file_path = home + "/.registerService/";
        const char *str1 = log_file_path.c_str();
        memcpy(&file_path, str1, sizeof(log_file_path));
        if(access(file_path, F_OK) != 0) {     //目录不存在
            std::string build_path ="mkdir -p ";
            build_path += file_path;
            system(build_path.c_str());
        }
        QString filepath1=QString::fromStdString(log_file_path)+"registerService.txt";
        //重新写入文件
        QFile filewirt(filepath1);
          if(i==1){
              filewirt.open(QIODevice::WriteOnly );
          }else if(i==2){
              filewirt.open(QIODevice::WriteOnly | QIODevice::Append);
          }

        QTextStream ts(&filewirt);
        ts.setCodec(QTextCodec::codecForName("UTF-8"));
        for (int j = 0; j < msgs.size(); ++j) {
            QString OutTxt =msgs[j];
            ts << OutTxt << endl;
          //  show_console(OutTxt,"get");
        }


    }catch (std::exception e){

    }

//-------------------------------------------------


}
//读取 registerService.txt 文件中数据
void RegisterService::readFile(map<QString, QString> &macMap){
    try {
        QFile file(QString::fromStdString(log_file_path)+"registerService.txt");
        if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qDebug()<<"Can't open the file!"<<endl;
        }
        while(!file.atEnd()) {
            QByteArray line = file.readLine();
            QString msg(line);
            //解析文件数据
            parseMoveScript(msg,macMap);
        }
    }catch(exception e){
        qDebug()<< "读取路点数据文件 moveScript.txt 异常！";
    }
}

//解析 registerService.txt 文件数据
void RegisterService::parseMoveScript(QString & msg,map<QString, QString> &macMap){

    try {
        //去除所有空白
        QString  msg0 = msg.remove(QRegExp("\\s"));
        //去掉注释,与空白的部分
        if (msg0.contains("#")||msg0.size()==0)
            return;

        //读取小车的中心点位置
        if(msg0.contains("mac")){

            QStringList msglist2 = msg0.split("-");
            QString mac = msglist2[1];//注册码
            macMap["mac"]=mac;
            //qDebug()<< "macMap[mac]： "<<mac;
        }else if(msg0.contains("econde")){//
            //
            QStringList msglist2 = msg0.split("-");
            QString encond = msglist2[1];//注册码
            macMap["econde"]=encond;
            //qDebug()<< "macMap[econde]： "<< encond;

        }else if(msg0.contains("checkenconde")){//
            //
            QStringList msglist2 = msg0.split("-");
            QString checkencond = msglist2[1];//授权码
            macMap["checkenconde"]=checkencond;
           // qDebug()<< "macMap[checkenconde]： "<<checkencond;
        }
    }catch(exception e){
        qDebug()<< "解析数据文件 indoor.yaml 异常！";
    }




}

/**
 * 显示日志
 */

void RegisterService::show_console(QString msg_log,QString send) {


    try {

        char response[1320];
        time_t tt;
        char buf[16] = {0};
        char buf1[16] = {0};
        tt = time(NULL);
        //清除char缓存
        memset(response, 0, 320);
        strftime(buf, 16, "%y-%m-%d %H:%M:%S", localtime(&tt));
        QString qss="[本地时间: "+QString(buf)+" ]";
        QByteArray ba = qss.toLocal8Bit();
        memcpy(response, ba.data(), ba.size());

        //log显示
        if (send == "send") {//发送消息
            logTextEdit.append(recv_prefix_red + response + msg_log);

        } else if (send == "get") {//接收到消息
            logTextEdit.append(recv_prefix_green + QString(response) + msg_log);

        }

        QString msg1 = QString(buf);
        msg1 = "[本地时间: "+msg1+"] "+msg_log;
        QByteArray array = msg1.toLocal8Bit();
        memcpy(response, array.data(), array.size());
        strftime(buf1, 16, "%y_%m_%d", localtime(&tt));
        QString logfileTimeName = QString(buf1);
        Log_Save(response,logfileTimeName);



    }catch (std::exception e){
        e.what();

    }

}

/**
 * 保存日志
 * showLog1
 */
void RegisterService::Log_Save(const char*str,QString logfileTimeName)
{

//自动创建目录
//--------------------还没测试-----------------------------

    try {
        char file_path[1500] = {0};
        std::string home = getenv("HOME");
        std::string log_file_path = home + "/Log_robot/";
        const char *str1 = log_file_path.c_str();
        memcpy(&file_path, str1, sizeof(log_file_path));
        if(access(file_path, F_OK) != 0) {     //目录不存在
            std::string build_path ="mkdir -p ";
            build_path += file_path;
            system(build_path.c_str());
        }

        QString OutTxt(str);
        QString filepath1=QString::fromStdString(log_file_path)+logfileTimeName+"A.txt";
        QString filepath2=QString::fromStdString(log_file_path)+logfileTimeName+"B.txt";

        QFile outFile1((filepath1));
        QFile outFile2((filepath2));
        outFile1.open(QIODevice::WriteOnly | QIODevice::Append);
        if(outFile1.size() >= 1024*100)
        {
            outFile1.close();
            outFile2.remove();
            QFile::copy((filepath1),(filepath2));
            outFile1.remove();
            QFile outFile3((filepath1));
            outFile3.open(QIODevice::WriteOnly | QIODevice::Append);
            QTextStream ts(&outFile3);
            ts.setCodec(QTextCodec::codecForName("UTF-8"));
            ts << OutTxt << endl;
        }
        else
        {
            QTextStream ts(&outFile1);
            ts.setCodec(QTextCodec::codecForName("UTF-8"));
            ts << OutTxt << endl;
        }

    }catch (std::exception e){

    }

//-------------------------------------------------


}



/**
 * 清除日志
 */
void RegisterService::clear_log() {

    logTextEdit.clear();
}
//初始话
void RegisterService::initvariable(){
    editFirst->clear();
    editSecond->clear();
        editThird->clear();
        editFifth->clear();
}




/**
正则表达式用于字符串处理、表单验证等场合，实用高效。现将一些常用的表达式收集于此，以备不时之需。
匹配中文字符的正则表达式： [\u4e00-\u9fa5]
评注：匹配中文还真是个头疼的事，有了这个表达式就好办了

匹配双字节字符(包括汉字在内)：[^\x00-\xff]
评注：可以用来计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）

匹配空白行的正则表达式：\n\s*\r
        评注：可以用来删除空白行

        匹配HTML标记的正则表达式：<(\S*?)[^>]*>.*?</\1>|<.*? />
评注：网上流传的版本太糟糕，上面这个也仅仅能匹配部分，对于复杂的嵌套标记依旧无能为力

        匹配首尾空白字符的正则表达式：^\s*|\s*$
评注：可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式

        匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注：表单验证时很实用

        匹配网址URL的正则表达式：[a-zA-z]+://[^\s]*
评注：网上流传的版本功能很有限，上面这个基本可以满足需求

        匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$
        评注：表单验证时很实用

        匹配国内电话号码：\d{3}-\d{8}|\d{4}-\d{7}
评注：匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号：[1-9][0-9]{4,}
评注：腾讯QQ号从10000开始

        匹配中国邮政编码：[1-9]\d{5}(?!\d)
评注：中国邮政编码为6位数字

        匹配身份证：\d{15}|\d{18}
评注：中国的身份证为15位或18位

        匹配ip地址：\d+\.\d+\.\d+\.\d+
评注：提取ip地址时有用

        匹配特定数字：
^[1-9]\d*$　 　 //匹配正整数
^-[1-9]\d*$ 　 //匹配负整数
^-?[1-9]\d*$　　 //匹配整数
^[1-9]\d*|0$　 //匹配非负整数（正整数 + 0）
^-[1-9]\d*|0$　　 //匹配非正整数（负整数 + 0）
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$　　 //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$　 //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$　 //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$　　 //匹配非负浮点数（正浮点数 + 0）
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$　　//匹配非正浮点数（负浮点数 + 0）
评注：处理大量数据时有用，具体应用时注意修正

        匹配特定字符串：
^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串
^[A-Z]+$　　//匹配由26个英文字母的大写

 */
